package com.css.zfzx.sjcj.common.spacedata;

import com.alibaba.fastjson.JSONObject;
import com.css.bpm.platform.base.response.RestResponse;
import com.css.zfzx.sjcj.common.spacedata.code.service.BaseDivisionService;
import com.css.zfzx.sjcj.common.spacedata.code.vo.DivisionVO;
import com.css.zfzx.sjcj.common.spacedata.vo.SpaceDataParamsVo;
import com.css.zfzx.sjcj.modules.hddcA6WaveformTable.service.HddcA6WaveformtableService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @Author zyc
 * @Date 2021/1/13 15:32
 * @Version V1.0
 */
@Slf4j
@RestController
@RequestMapping("/hddc/hddcShpDataMapDisplay")
public class SpaceFilesDataController {

    @Autowired
    HddcA6WaveformtableService hddcA6WaveformtableService;
    @Autowired
    BaseDivisionService baseDivisionService;
    @Autowired
    private SpacedataAnalysis spacedataanalysis;
    //获取配置文件的上传文件路径
    @Value("${file.upload.path}")
    private String uploadPath;

    /**
     * 批量上传文件
     *
     * @param files
     * @param paramsVo
     * @return
     */
    @PostMapping("/upload")
    public RestResponse uploadSpaceData(@RequestParam("files") MultipartFile[] files, SpaceDataParamsVo paramsVo) {
        //数据校验
        if (files == null && files.length <= 0) {
            return RestResponse.fail("上传失败，请选择文件");
        }
        if (StringUtils.isEmpty(paramsVo.getType())) {
            return RestResponse.fail("上传失败，传入类型不能为空");
        }
        // 返回的消息
        StringBuilder returnMsg = new StringBuilder();
        String jxfilename = "";
        String dbffilename = "";
        String savefilename = files[0].getOriginalFilename().substring(0, files[0].getOriginalFilename().lastIndexOf("."));
        //循环处理每一个文件
        for (MultipartFile file : files) {
            //获取上传原文件名称
            String oldFileName = file.getOriginalFilename();
            // 上传后文件名
            String newFileName = paramsVo.getType() + "_&_" + (paramsVo.getProvinceCode() == null ? "0" : paramsVo.getProvinceCode())
                    + "_&_" + (paramsVo.getCityCode() == null ? "0" : paramsVo.getCityCode()) + "_&_" + (paramsVo.getAreaCode() == null ? "0" : paramsVo.getAreaCode()) + "_&_" + oldFileName;
            if (newFileName.contains(".shp") && !newFileName.contains(".xml")) {
                jxfilename = newFileName;
            }
            if (oldFileName.contains(".dbf")) {
                dbffilename = newFileName;
            }
            File savefile = new File(uploadPath + newFileName);
            File absoluteFile = savefile.getAbsoluteFile();
            if (!absoluteFile.getParentFile().exists()) {
                absoluteFile.getParentFile().mkdirs();
            }
            try {
                file.transferTo(absoluteFile);
                returnMsg.append(newFileName);
                returnMsg.append(",");
            } catch (IOException e) {
                e.printStackTrace();
                return RestResponse.fail(newFileName + "上传失败");
            }
        }
        try {
            String[] paramdatas = VectorDataUtil.getFieldName(uploadPath + dbffilename, "GBK");
            Boolean flag = spacedataanalysis.judgeFileParams(paramdatas, paramsVo.getType());
            if (!flag) {
                //todo:删除对应的文件
                List<SpaceDataParamsVo> paramsVos = new ArrayList<>();
                paramsVos.add(paramsVo);
                deleteFiles(paramsVos);
                return RestResponse.fail("导入数据参数不正确，参数个数低于当前空间数据个数！");

            }
            String resultMsg = returnMsg.substring(0, returnMsg.length() - 1);
            List<List<Object>> list = VectorDataUtil.readSHPFile(uploadPath + jxfilename, 1);
            if (list.size() > 0) {
                for (int j = 0; j < list.size(); j++) {
                    for (int i = 1; i < list.get(0).size(); i++) {
                        if (list.get(j).get(i) == null) {
                            return RestResponse.fail("导入.dbf文件的属性信息不能为 null。");
                        }
                    }
                }
            }
            boolean hasGarbled = false;
            if (list.size() > 0) {
                for (int j = 0; j < list.size(); j++) {
                    for (int i = 1; i < list.get(j).size(); i++) {
                        if (list.get(j).get(i) == null) {
                            continue;
                        }
                        String strstr = list.get(j).get(i).toString();
                        boolean result = testtest(strstr);
                        if (result) {
                            hasGarbled = true;
                            break;
                        }
                    }
                }
            }
            if (hasGarbled) {
                list = VectorDataUtil.readSHPFile(uploadPath + jxfilename, 0);
                if (list.size() > 0) {
                    for (int j = 0; j < list.size(); j++) {
                        for (int i = 1; i < list.get(j).size(); i++) {
                            if (list.get(j).get(i) == null) {
                                continue;
                            }
                            String strstr = list.get(j).get(i).toString();
                            boolean result = testtest(strstr);
                            if (result) {
                                return RestResponse.fail("导入.dbf文件的属性的第【" + i + "】条数据信息有乱码。");
                            }
                        }
                    }
                }
            }
            paramsVo.setSavefilename(savefilename);
            spacedataanalysis.saveFileDatas(list, paramsVo);
//        if(false){
//            return RestResponse.fail("导入shp文件数据类型与文字说明不匹配，请检查导入文件的数据类型！");
//        }
            return RestResponse.succeed(resultMsg + "上传成功");
        }catch (Exception ex){
            return RestResponse.fail(ex.getMessage());
        }
    }

    public boolean testtest(String str) {
        for (int i = 0; i < str.length(); i++) {
            /*if(=="#"){
                continue;
            }*/
            char c = str.charAt(i);
            // 当从Unicode编码向某个字符集转换时，如果在该字符集中没有对应的编码，则得到0x3f（即问号字符?）
            //从其他字符集向Unicode编码转换时，如果这个二进制数在该字符集中没有标识任何的字符，则得到的结果是0xfffd
            if ((int) c == 0xfffd) {
                // 存在乱码
                return true;
            }
        }
        return false;
    }

    @GetMapping("/getValidDictItemsByDictCode/{dictCode}")
    public RestResponse getValidDictItemsByDictCode(@PathVariable String dictCode) {
        RestResponse restResponse = null;
        try {
            restResponse = RestResponse.succeed(hddcA6WaveformtableService.getValidDictItemsByDictCode(dictCode));
        } catch (Exception e) {
            String errorMsg = "字典项获取失败!";
            restResponse = RestResponse.fail(errorMsg);
        }
        return restResponse;
    }


    /**
     * 批量下载文件
     *
     * @param response
     * @param provinceCode
     * @param cityCode
     * @param areaCode
     * @param type
     * @return
     */
    @GetMapping("/download")
    public RestResponse downloadFile(HttpServletResponse response, String provinceCode,
                                     String cityCode, String areaCode, String type) {
        SpaceDataParamsVo paramsVo = new SpaceDataParamsVo();
        paramsVo.setProvinceCode(provinceCode);
        paramsVo.setCityCode(cityCode);
        paramsVo.setAreaCode(areaCode);
        paramsVo.setType(type);
        if (StringUtils.isEmpty(paramsVo.getType())) {
            return RestResponse.fail("下载失败，请选择下载文件的类型");
        }
        //获取指定路径下的所有文件名
        File file = new File(uploadPath);
        File[] files = file.listFiles();
        if (files == null) {
            return RestResponse.fail("下载失败，该目录下不存在文件");
        }
        //根据参数生成文件名前缀
        String selectPrefix = paramsVo.getType() + "_&_" + (paramsVo.getProvinceCode() == null ? "0" : paramsVo.getProvinceCode())
                + "_&_" + (paramsVo.getCityCode() == null ? "0" : paramsVo.getCityCode()) + "_&_" + (paramsVo.getAreaCode() == null ? "0" : paramsVo.getAreaCode());
        List<File> zipFiles = new ArrayList<>();
        for (File f : files) {
            if (f.getName().contains("_&_")) {
                String filePrefix = f.getName().substring(0, f.getName().lastIndexOf("_&_"));
                if (filePrefix.equals(selectPrefix)) {
                    zipFiles.add(f);
                }
            }
        }
        StringBuffer sb = new StringBuffer();
        if (!CollectionUtils.isEmpty(zipFiles)) {
            String zipName = paramsVo.getType() + "_" + (paramsVo.getProvinceCode() == null ? "0" : paramsVo.getProvinceCode())
                    + "_" + (paramsVo.getCityCode() == null ? "0" : paramsVo.getCityCode()) + "_" + (paramsVo.getAreaCode() == null ? "0" : paramsVo.getAreaCode()) + ".zip";
            String msg = ZipDownloadUtil.zipDownload(response, uploadPath, zipName, zipFiles);
            sb.append(msg);
        } else {
            sb.append("没有可下载文件");
        }
        return RestResponse.succeed(sb);
    }

    @DeleteMapping("/deleteFileData")
    public RestResponse deleteFileData(@RequestParam SpaceDataParamsVo paramsVo) {
        RestResponse response = null;
        JSONObject json = new JSONObject();
        try {
            spacedataanalysis.deleteFileData(paramsVo);
            json.put("message", "删除成功!");
            response = RestResponse.succeed(json);
        } catch (Exception e) {
            String errorMessage = "删除失败!";
            log.error(errorMessage, e);
            response = RestResponse.fail(errorMessage);
        }
        return response;
    }


    @RequestMapping("/download-multipl")
    public RestResponse downloadMultiplFile(HttpServletResponse response, String downParams) {
        if (StringUtils.isEmpty(downParams)) {
            return RestResponse.fail("下载条件不能为空");
        }
        String[] params = downParams.split(";");
        List<SpaceDataParamsVo> spaceDataParamsVos = new ArrayList<>();
        for (String param : params) {
            SpaceDataParamsVo vo = new SpaceDataParamsVo();
            String[] split = param.split(",");
            vo.setProvinceName(split[0]);
            vo.setCityName(split[1]);
            vo.setAreaName(split[2]);
            vo.setType(split[3]);
            vo.setSavefilename(split[4]);
            spaceDataParamsVos.add(vo);
        }
        if (CollectionUtils.isEmpty(spaceDataParamsVos)) {
            return RestResponse.fail("下载条件不能为空");
        }
        //获取指定路径下的所有文件名
        File file = new File(uploadPath);
        File[] files = file.listFiles();
        if (files == null) {
            return RestResponse.fail("下载失败，该目录下不存在文件");
        }
        List<File> zipFiles = new ArrayList<>();
        for (SpaceDataParamsVo paramsVo : spaceDataParamsVos) {
            if (StringUtils.isEmpty(paramsVo.getType())) {
                return RestResponse.fail("下载失败，请选择下载文件的类型");
            }
            // 省市县中文转代码
            DivisionVO divisionVO = new DivisionVO();
            divisionVO.setProvince(paramsVo.getProvinceName());
            divisionVO.setCity(paramsVo.getCityName());
            divisionVO.setArea(paramsVo.getAreaName());
            paramsVo.setProvinceCode(baseDivisionService.findDivisionCodeByName(divisionVO, "1"));
            paramsVo.setCityCode(baseDivisionService.findDivisionCodeByName(divisionVO, "2"));
            paramsVo.setAreaCode(baseDivisionService.findDivisionCodeByName(divisionVO, "3"));
            //根据参数生成文件名前缀
            String selectPrefix = paramsVo.getType() + "_&_" + (paramsVo.getProvinceCode() == "" ? "null" : paramsVo.getProvinceCode())
                    + "_&_" + (paramsVo.getCityCode() == "" ? "null" : paramsVo.getCityCode()) + "_&_" + (paramsVo.getAreaCode() == "" ? "null" : paramsVo.getAreaCode())
                    + "_&_" + paramsVo.getSavefilename();

            for (File f : files) {
                if (f.getName().contains("_&_")) {
                    /*String filePrefix = f.getName().substring(0, f.getName().lastIndexOf("_&_"));
                    if (filePrefix.equals(selectPrefix)) {
                        zipFiles.add(f);
                    }*/
                    if (f.getName().contains(selectPrefix)){
                        zipFiles.add(f);
                    }
                }
            }

        }
        StringBuffer sb = new StringBuffer();
        if (!CollectionUtils.isEmpty(zipFiles)) {

            String zipName = "下载数据.zip";
            if(params.length>0){
                String name="";
                String[] split = params[0].split(",");
                if(split[0]!=null&&split[0]!=""){
                    name+=split[0]+"-";
                }
                if(split[1]!=null&&split[1]!=""){
                    name+=split[1]+"-";
                }
                if(split[2]!=null&&split[2]!=""){
                    name+=split[2]+"-";
                }
                name+=getFileNameFromID(split[3]);
                zipName=name+".zip";
            }

            //zipName=getFileNameFromID("2");
            String msg = ZipDownloadUtil.zipDownload(response, uploadPath, zipName, zipFiles);
            sb.append(msg);
        } else {
            sb.append("没找到您要下载的文件");
        }
        return RestResponse.succeed(sb);
    }

    private String getFileNameFromID(String id){
        if(id.equals("1")){
            return "地质调查规划路线-线";
        }else if(id.equals("2")){
            return "主要活动断层制图区-面";
        }else if(id.equals("3")){
            return "面状资料图层-面";
        }else if(id.equals("4")){
            return "目标区-面";
        }else if(id.equals("5")){
            return "工作区-面";
        }else if(id.equals("6")){
            return "影像索引表-面";
        }else if(id.equals("7")){
            return "航、卫片解译线-线";
        }else if(id.equals("8")){
            return "航、卫片解译面-面";
        }else if(id.equals("9")){
            return "航磁-线";
        }else if(id.equals("10")){
            return "地壳厚度-线";
        }else if(id.equals("11")){
            return "重磁解译线-线";
        }else if(id.equals("12")){
            return "重力场-线";
        }else if(id.equals("13")){
            return "垂直形变-线";
        }else if(id.equals("14")){
            return "1：1万底图岩体线-线";
        }else if(id.equals("15")){
            return "1：1万工作底图岩体-面";
        }else if(id.equals("16")){
            return "1：25万底图岩体线-线";
        }else if(id.equals("17")){
            return "1：25万工作底图岩体-面";
        }else if(id.equals("18")){
            return "1：5万底图岩体线-线";
        }else if(id.equals("19")){
            return "1：5万工作底图岩体-面";
        }else if(id.equals("20")){
            return "1：1万底图地层线-线";
        }else if(id.equals("21")){
            return "1：1万工作底图地层-面";
        }else if(id.equals("22")){
            return "1：25万底图地层线-线";
        }else if(id.equals("23")){
            return "1：25万工作底图地层-面";
        }else if(id.equals("24")){
            return "1：5万底图地层线-线";
        }else if(id.equals("25")){
            return "1：5万工作底图地层-面";
        }else if(id.equals("26")){
            return "活动断层-线";
        }else if(id.equals("27")){
            return "地质调查路线-线";
        }else if(id.equals("28")){
            return "地貌线-线";
        }else if(id.equals("29")){
            return "地貌面-面";
        }else if(id.equals("30")){
            return "地质剖面线-线";
        }else if(id.equals("31")){
            return "微地貌测量线-线";
        }else if(id.equals("32")){
            return "微地貌测量面-面";
        }else if(id.equals("33")){
            return "微地貌面测量切线-线";
        }else if(id.equals("34")){
            return "跨断层钻探剖面-线";
        }else if(id.equals("35")){
            return "地球物理测线-线";
        }else if(id.equals("36")){
            return "地球化学异常区段-线";
        }else if(id.equals("37")){
            return "地球化学探测测线-线";
        }else if(id.equals("38")){
            return "熔岩流-面";
        }else if(id.equals("39")){
            return "活动断层位置误差";
        }


        return id;
    }

    /**
     * 删除文件
     *
     * @param paramsVos
     */
    //@DeleteMapping("/deletefile")
    @RequestMapping("/deletefile")
    public RestResponse deleteFiles(@RequestBody List<SpaceDataParamsVo> paramsVos) {

        //获取指定路径下的所有文件名
        File file = new File(uploadPath);
        File[] files = file.listFiles();
        if (files == null || files.length == 0) {
            return RestResponse.fail("无可删除的文件");
        }
        StringBuffer sb = new StringBuffer();
        for (SpaceDataParamsVo paramsVo : paramsVos) {
            // 省市县中文转代码
            DivisionVO divisionVO = new DivisionVO();
            divisionVO.setProvince(paramsVo.getProvinceName());
            divisionVO.setCity(paramsVo.getCityName());
            divisionVO.setArea(paramsVo.getAreaName());
            paramsVo.setProvinceCode(baseDivisionService.findDivisionCodeByName(divisionVO, "1"));
            paramsVo.setCityCode(baseDivisionService.findDivisionCodeByName(divisionVO, "2"));
            paramsVo.setAreaCode(baseDivisionService.findDivisionCodeByName(divisionVO, "3"));
            //根据参数生成文件名前缀
            String selectPrefix = paramsVo.getType() + "_&_" + (paramsVo.getProvinceCode() == null ? "0" : paramsVo.getProvinceCode())
                    + "_&_" + (paramsVo.getCityCode() == null ? "0" : paramsVo.getCityCode()) + "_&_" + (paramsVo.getAreaCode() == null ? "0" : paramsVo.getAreaCode()) + "_&_" + paramsVo.getSavefilename();
            for (File f : files) {
                String filePrefix = f.getName().substring(0, f.getName().lastIndexOf("."));
                if (filePrefix.equals(selectPrefix)) {
                    sb.append(f.getName());
                    sb.append(",");
                    f.delete();
                }
            }
            spacedataanalysis.deleteFileData(paramsVo);
        }
        String message = null;
        if (sb.toString().length() == 0) {
            message = "不存在该区域的文件";
        } else {
            message = (sb.toString().substring(0, sb.toString().lastIndexOf(","))) + "删除成功！";
        }
        return RestResponse.succeed(message);
    }


}
